package com.xuzimian.globaldemo.designpatterns.proxy.dynamic;


import com.xuzimian.globaldemo.designpatterns.proxy.ISubject;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import javassist.util.proxy.ProxyObject;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Method;

import static java.lang.System.out;

public class JavassistProxyTest {

    @Test
    public void test() {
        ProxyFactory proxyFactory = new ProxyFactory();

        proxyFactory.setInterfaces(new Class[]{ISubject.class});

        Class proxyClass = proxyFactory.createClass();

        ISubject javassistProxy = null;

        try {
            javassistProxy = (ISubject) proxyClass.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }

        assert javassistProxy != null;
        ((ProxyObject) javassistProxy).setHandler(new JavassistHandler(new ISubject() {
            @Override
            public String processBusiness() {
                out.println("Method processBusiness call by JavassistProxyTest");
                return "Javassist";
            }
        }));

        javassistProxy.processBusiness();
    }

}

class JavassistHandler implements MethodHandler {
    private Object target;

    public JavassistHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
        doBefore();

        Object result = thisMethod.invoke(target, args);

        doAfter();

        return result;
    }

    private void doBefore() {
        out.println("Before ...");
    }

    private void doAfter() {
        out.println("After ...");
    }
}
